package com.bilibili.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bilibili.dao.FollowingGroupMapper;
import com.bilibili.dao.UserFollowingMapper;
import com.bilibili.dao.UserInfoMapper;
import com.bilibili.dao.UserMapper;
import com.bilibili.domain.constant.UserConstant;
import com.bilibili.domain.entity.FollowingGroup;
import com.bilibili.domain.entity.User;
import com.bilibili.domain.entity.UserFollowing;
import com.bilibili.domain.entity.UserInfo;
import com.bilibili.domain.exception.ConditionException;
import com.bilibili.service.FollowingGroupService;
import com.bilibili.service.UserFollowingService;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author www
* @description 针对表【t_user_following(用户关注表)】的数据库操作Service实现
* @createDate 2024-06-04 15:12:44
*/
@Service
public class UserFollowingServiceImpl extends ServiceImpl<UserFollowingMapper, UserFollowing>
    implements UserFollowingService {

    @Resource
    private FollowingGroupService followingGroupService;
    @Resource
    private FollowingGroupMapper followingGroupMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserFollowingMapper userFollowingMapper;
    @Resource
    private UserInfoMapper userInfoMapper;

    LambdaQueryWrapper<UserFollowing> wrapper = new LambdaQueryWrapper<>();
    LambdaQueryWrapper<FollowingGroup> groupWrapper = new LambdaQueryWrapper<>();
    LambdaQueryWrapper<UserInfo> infoWrapper = new LambdaQueryWrapper<>();

    @Override
    @Transactional
    public void addUserFollowings(UserFollowing userFollowing) {
        Long groupId = userFollowing.getGroupId();
        if (groupId == null) {
            FollowingGroup followingGroup =
                    followingGroupService.getByType(UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT);
            userFollowing.setGroupId(followingGroup.getId());
        } else {
            FollowingGroup followingGroup = followingGroupMapper.selectById(userFollowing.getGroupId());
            if (followingGroup == null) {
                throw new ConditionException("关注的分组不存在！");
            }
        }
        Long followingId = userFollowing.getFollowingId();
        User user = userMapper.selectById(followingId);
        if (user == null) {
            throw new ConditionException("关注的用户不存在！");
        }
        wrapper.eq(UserFollowing::getUserId, userFollowing.getUserId())
                .eq(UserFollowing::getFollowingId, followingId);
        //更新
        userFollowingMapper.delete(wrapper);
        userFollowing.setCreateTime(new Date());
        userFollowingMapper.insert(userFollowing);
    }

    @Override
    public List<FollowingGroup> getUserFollowings(Long userId) {
        wrapper.eq(UserFollowing::getUserId, userId);
        //1.获取用户列表
        List<UserFollowing> list = userFollowingMapper.selectList(wrapper);
        //2.根据关注用户的id查询关注用户的基本信息
        Set<Long> followingIdSet = list.stream()
                .map(UserFollowing::getFollowingId)
                .collect(Collectors.toSet());
        List<UserInfo> userInfoList = new ArrayList<>();
        if (followingIdSet.size() > 0) {
            userInfoList = userInfoMapper.selectByUserIds(followingIdSet);
        }
        for (UserFollowing userFollowing : list) {
            for (UserInfo userInfo : userInfoList) {
                if (userFollowing.getFollowingId().equals(userInfo.getUserId())) {
                    userFollowing.setUserInfo(userInfo);
                }
            }
        }
        //3.将关注用户按关注分组进行分类
        groupWrapper.eq(FollowingGroup::getUserId, userId);
        List<FollowingGroup> followingGroups = followingGroupMapper.selectList(groupWrapper);
        FollowingGroup allGroup = new FollowingGroup();
        allGroup.setName(UserConstant.USER_FOLLOWING_GROUP_ALL_NAME);
        allGroup.setFollowingUserInfoList(userInfoList);
        List<FollowingGroup> result = new ArrayList<>();
        for (FollowingGroup followingGroup : followingGroups) {
            List<UserInfo> infoList = new ArrayList<>();
            for (UserFollowing userFollowing : list) {
                if (followingGroup.getId().equals(userFollowing.getGroupId())) {
                    infoList.add(userFollowing.getUserInfo());
                }
            }
            followingGroup.setFollowingUserInfoList(infoList);
            result.add(followingGroup);
        }
        return result;
    }

    @Override
    public List<UserFollowing> getUserFans(Long userId) {
        //1.获取当前用户粉丝列表
        wrapper.eq(UserFollowing::getFollowingId, userId);
        List<UserFollowing> fansList = userFollowingMapper.selectList(wrapper);
        //2.根据粉丝的用户id查询基本信息
        Set<Long> fansIdSet = fansList.stream().map(UserFollowing::getUserId).collect(Collectors.toSet());
        List<UserInfo> userInfoList = new ArrayList<>();
        if (fansIdSet.size() > 0) {
            userInfoList = userInfoMapper.selectByUserIds(fansIdSet);
        }
        //3.查询当前用户是否已经关注该粉丝
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserFollowing::getUserId, userId);
        List<UserFollowing> followingList = userFollowingMapper.selectList(wrapper);
        for (UserFollowing fan : fansList) {
            for (UserInfo userInfo : userInfoList) {
                if (fan.getUserId().equals(userInfo.getUserId())) {
                    userInfo.setFollowed(false);
                    fan.setUserInfo(userInfo);
                }
            }
            //互相关注
            for (UserFollowing userFollowing : followingList) {
                if (userFollowing.getFollowingId().equals(fan.getUserId())) {
                    fan.getUserInfo().setFollowed(true);
                }
            }
        }
        return fansList;
    }

    @Override
    public List<UserInfo> checkFollowingStatus(List<UserInfo> list, Long userId) {
        wrapper.eq(UserFollowing::getFollowingId,userId);
        List<UserFollowing> followingList = userFollowingMapper.selectList(wrapper);
        for (UserInfo userInfo : list) {
            userInfo.setFollowed(false);
            for (UserFollowing userFollowing : followingList) {
                if (userFollowing.getFollowingId()==userInfo.getUserId()){
                    userInfo.setFollowed(true);
                }
            }
        }
        return list;
    }
}




